package com.pro.common.service.pay.service;

import com.pro.common.api.depencies.model.mapstruct.LoginInfoMapper;
import com.pro.common.api.enums.EnumOrderEntityType;
import com.pro.common.api.model.LoginInfo;
import com.pro.common.api.model.request.pay.IEnumPaymentBizType;
import com.pro.common.api.model.mq.PaymentNotifyDataBusiness;
import com.pro.common.api.model.request.pay.PaymentParamsDTO;
import com.pro.common.api.pay.enums.EnumPaymentStatus;
import com.pro.common.api.pay.model.db.PaymentOrder;
import com.pro.common.modules.service.dependencies.util.TransactionUtil;
import com.pro.common.service.pay.dao.PaymentOrderDao;
import com.pro.common.api.pay.model.db.PayMerchant;
import com.pro.common.api.pay.model.db.PaymentChannel;
import com.pro.common.service.pay.model.mapstruct.PaymentOrderMapper;
import com.pro.common.service.pay.mq.PayMqProducer;
import com.pro.framework.api.util.AssertUtil;
import com.pro.framework.mybatisplus.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Map;

/**
 * ${label}服务
 */
@Service
@Slf4j
public class PaymentOrderService extends BaseService<PaymentOrderDao, PaymentOrder> {
    @Autowired
    private PaymentOrderMapper mapper;
    @Autowired
    private LoginInfoMapper loginInfoMapper;
    @Autowired
    private PayMqProducer payMqProducer;

    /**
     * 创建支付订单
     */
    public PaymentOrder save(LoginInfo loginInfo, PaymentParamsDTO paymentParamsDTO, PaymentChannel channel, PayMerchant merchant) {
        PaymentOrder paymentOrder = new PaymentOrder();
        loginInfoMapper.update(loginInfo, paymentOrder);
        mapper.updateFromParams(paymentParamsDTO, paymentOrder);
        mapper.updateChannel(channel, paymentOrder);
        mapper.updateMerchant(merchant, paymentOrder);
        paymentOrder.setNo(TransactionUtil.generateOrderNo(EnumOrderEntityType.paymentOrder));
        paymentOrder.setPayMerchantId(merchant.getId());
        this.save(paymentOrder);
        return paymentOrder;
    }

    /**
     * 代收回调返回
     */
    public void paymentEnd(String no, BigDecimal payAmount, String outId, Boolean success, PayMerchant merchant) {
        PaymentOrder param = new PaymentOrder();
        param.setNo(no);
        PaymentOrder order = this.getOne(param);

        AssertUtil.notEmpty(order, "订单不存在_", no);
        AssertUtil.notEmpty(payAmount, "支付金额不为空");
        AssertUtil.isTrue(merchant.getId().equals(order.getPayMerchantId()), "支付通道不一致__", merchant.getId(), order.getPayMerchantId());
//        AssertUtil.notEmpty(payAmount.compareTo(order.getOrderAmount()) == 0, "支付金额错误");
        boolean update = this.lambdaUpdate()
                .set(PaymentOrder::getPayAmount, payAmount)
                .set(null != outId, PaymentOrder::getOutId, outId)
                .set(PaymentOrder::getUpdateTime, LocalDateTime.now())
                .set(PaymentOrder::getStatus, success ? EnumPaymentStatus.SUCCESS : EnumPaymentStatus.FAILED)
                .eq(PaymentOrder::getNo, no)
                .eq(PaymentOrder::getStatus, EnumPaymentStatus.PENDING)
                .update();
        AssertUtil.isTrue(update, "重复处理");


        // mq通知 业务订单 处理支付成功
        payMqProducer.sendPaymentCallback(getBizTypeMap().get(order.getBizType()), PaymentNotifyDataBusiness.builder()
                .bizType(order.getBizType())
                .bizId(order.getBizId())
                .payAmount(payAmount)
                .statusSuccess(success)
                .statusFail(!success)
                .build());
    }

    public Map<String, ? extends IEnumPaymentBizType> getBizTypeMap() {
        return Collections.emptyMap();
    }
}
